package pers.sloera.leetcode.lemonadeChange;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * 860. 柠檬水找零
 * <p>
 * 在柠檬水摊上，每一杯柠檬水的售价为 5 美元。
 * <p>
 * 顾客排队购买你的产品，（按账单 bills 支付的顺序）一次购买一杯。
 * <p>
 * 每位顾客只买一杯柠檬水，然后向你付 5 美元、10 美元或 20 美元。你必须给每个顾客正确找零，也就是说净交易是每位顾客向你支付 5 美元。
 * <p>
 * 注意，一开始你手头没有任何零钱。
 * <p>
 * 如果你能给每位顾客正确找零，返回 true ，否则返回 false 。
 *
 * @author SloeraN
 * @version 1.0
 * @class pers.sloera.leetcode.lemonadeChange.Solution
 * @date 2020/12/10
 */
public class Solution {
    public static void main(String[] args) {
        Solution solution = new Solution();
        boolean b = solution.lemonadeChange(new int[]{5, 5, 5, 10, 20});
        System.out.println(b);
    }


    /**
     * 计算是否可找零成功
     *
     * @param bills 输入的金额
     * @return boolean 找零成功{@code true}。
     * @date 2020/12/11
     */
    public boolean lemonadeChange(int[] bills) {
        AtomicInteger fiveAtomic = new AtomicInteger(0);
        AtomicInteger tenAtomic = new AtomicInteger(0);
        AtomicInteger twentyAtomic = new AtomicInteger(0);
        for (int i = 0; i < bills.length; i++) {
            // 1. 钱先入账
            switch (bills[i]) {
                case 5:
                    fiveAtomic.getAndIncrement();
                    break;
                case 10:
                    tenAtomic.getAndIncrement();
                    break;
                case 20:
                    twentyAtomic.getAndIncrement();
                    break;
                default:
                    return false;
            }
            // 2. 分三个面值判断是否可找零
            if (!canChange(fiveAtomic, tenAtomic, twentyAtomic, bills[i] - 5)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 从面值最大的20开始，进行找零
     *
     * @param fiveAtomic 5元面值个数
     * @param tenAtomic 10元面值个数
     * @param twentyAtomic 20元面值个数
     * @param bill 待找零数
     * @return boolean 找零成功{@code true}
     * @date 2020/12/11
     */
    private boolean canChange(AtomicInteger fiveAtomic, AtomicInteger tenAtomic, AtomicInteger twentyAtomic, int bill) {
        if (bill == 0) {
            return true;
        }
        int twenty = bill / 20;
        if (twenty != 0) {
            if (twentyAtomic.get() >= twenty) {
                twentyAtomic.getAndAdd(-twenty);
                bill = bill % 20;
            }
        }
        int ten = bill / 10;
        if (ten != 0) {
            if (tenAtomic.get() >= ten) {
                tenAtomic.getAndAdd(-ten);
                bill = bill % 10;
            }
        }
        int five = bill / 5;
        if (five != 0) {
            if (fiveAtomic.get() >= five) {
                fiveAtomic.getAndAdd(-five);
                bill = bill % 5;
            } else {
                return false;
            }
        }
        return bill == 0;
    }

}
